package com.xhlj.config;

import com.xhlj.security.CustomUsernamePasswordAuthenticationFilter;
import com.xhlj.security.DbUserDetailsManager;
import com.xhlj.security.JwtAuthenticationFilter;
import com.xhlj.security.captcha.CaptchaLoginAuthenticationFilter;
import com.xhlj.security.captcha.CaptchaLoginAuthenticationProvider;
import com.xhlj.security.handler.CustomUsernamePasswordAuthenticationSuccessHandler;
import jakarta.annotation.Resource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.AuthenticationProvider;
import org.springframework.security.authentication.ProviderManager;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.SecurityFilterChain;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import static org.springframework.security.config.Customizer.withDefaults;

@Configuration
@EnableWebSecurity
public class WebSecurityConfig {


    /*处理验证码登录的Provider*/
    @Resource
    private CaptchaLoginAuthenticationProvider captchaLoginAuthenticationProvider;
    /*jwt filter*/
    @Resource
    private JwtAuthenticationFilter jwtAuthenticationFilter;

    /*认证管理器*/
    @Bean
    public AuthenticationManager authenticationManager(AuthenticationProvider... providers) {
        // 创建 AuthenticationManager 实例
        List<AuthenticationProvider> providerList = new ArrayList<>(Arrays.asList(providers));
        providerList.add(captchaLoginAuthenticationProvider);
        return new ProviderManager(providerList);

    }

    /*密码加密器*/
    @Bean
    PasswordEncoder passwordEncoder() {
        PasswordEncoder encoder = new BCryptPasswordEncoder();
        return encoder;
    }

    /*security 操作数据库的*/
    @Bean
    DbUserDetailsManager dbUserDetailsManager() {

        DbUserDetailsManager dbUserDetailsManager = new DbUserDetailsManager();
        return dbUserDetailsManager;
    }

    /*认证管理器 需要的Provider*/
    @Bean
    public DaoAuthenticationProvider daoAuthenticationProvider() {
        // 创建 DaoAuthenticationProvider 实例
        DaoAuthenticationProvider provider = new DaoAuthenticationProvider();

        // 设置 UserDetailsService
        provider.setUserDetailsService(dbUserDetailsManager());

        // 设置 PasswordEncoder
        provider.setPasswordEncoder(passwordEncoder());

        return provider;
    }

    @Resource
    CustomUsernamePasswordAuthenticationSuccessHandler customUsernamePasswordAuthenticationSuccessHandler;

    @Bean
    SecurityFilterChain filterChain(HttpSecurity http) throws Exception {
        CaptchaLoginAuthenticationFilter captchaLoginAuthenticationFilter = new CaptchaLoginAuthenticationFilter(authenticationManager());
        CustomUsernamePasswordAuthenticationFilter customUsernamePasswordAuthenticationFilter = new CustomUsernamePasswordAuthenticationFilter(authenticationManager());
//      放行登录相关的接口
        http.authorizeHttpRequests(authorize -> {
            authorize.requestMatchers("/login", "login/captcha", "login/getcaptcha", "register","logout","file/**","conference/**","activity/**","pay/**","notify/**","mj/**","chat/**","weixin/*").permitAll().anyRequest().authenticated();
        });
//        表单验证直接关掉，因为我们走请求体,要重写Username....
//        http.formLogin(form -> {
//            form.successHandler(customUsernamePasswordAuthenticationSuccessHandler);
//            form.loginProcessingUrl("/login");
//        });

        http.addFilterBefore(jwtAuthenticationFilter, CustomUsernamePasswordAuthenticationFilter.class);
        http.addFilterAfter(captchaLoginAuthenticationFilter, CustomUsernamePasswordAuthenticationFilter.class);


        http.cors(withDefaults());
        http.csrf(csrf -> csrf.disable());
        return http.build();
    }


}
